package cn.edu.cdu.farmdeal.service.impl;

import cn.edu.cdu.farmdeal.dto.BindUserDto;
import cn.edu.cdu.farmdeal.service.AuthService;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * @author tupeng
 * @date 2019/12/08
 * @Description TODO
 **/
@Service
public class QQAuthServiceImpl extends AuthServiceImpl implements AuthService {
    /**
     * 静态字符常量 qq登录的页面
     */
    private final static String AUTHORIZATION_URL =
            "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s";
    /**
     * 获取token的URL
     */
    private final static String ACCESS_TOKEN_URL =
            "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s";
    /**
     * 获取用户 openid 的 URL
     */
    private static final String OPEN_ID_URL = "https://graph.qq.com/oauth2.0/me?access_token=%s";
    /**
     * 获取用户信息的 URL，oauth_consumer_key 为 apiKey
     */
    private static final String USER_INFO_URL = "https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s";
    /**
     * 下面的属性可以通过配置读取
     *  QQ 在登陆成功后回调的 URL，这个 URL 必须在 QQ 互联里填写过
     *
     */
    private static final String CALLBACK_URL = "http://localhost:8080/oauth/qq/callback";
    /**
     * QQ 互联应用管理中心的 APP ID
     */
    private static final String APP_ID = "101831951";
    /**
     * QQ 互联应用管理中心的 APP Key
     */
    private static final String APP_SECRET = "98739b7a849739f5b3d20d83c2700bc0";
    /**
     * QQ 互联的 API 接口，访问用户资料
     */
    private static final String SCOPE = "get_user_info";


    @Override
    public String getAccessToken(String code) {
        String url = String.format(ACCESS_TOKEN_URL, APP_ID, APP_SECRET, code, CALLBACK_URL);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = builder.build().encode().toUri();
        String resp = getRestTemplate().getForObject(uri, String.class);
        if (resp != null && resp.contains("access_token")) {
            Map<String, String> map = getParam(resp);
            return map.get("access_token");
        }
        return "code无效";
    }
    private Map<String, String> getParam(String string) {
        Map<String, String> map = new HashMap();
        String[] kvArray = string.split("&");
        for (int i = 0; i < kvArray.length; i++) {
            String[] kv = kvArray[i].split("=");
            map.put(kv[0], kv[1]);
        }
        return map;
    }
    private JSONObject ConvertToJson(String string) {
        string = string.substring(string.indexOf("(") + 1, string.length());
        string = string.substring(0, string.indexOf(")"));
        JSONObject jsonObject = JSONObject.parseObject(string);
        return jsonObject;
    }
    @Override
    public String getOpenId(String accessToken) throws JSONException {
        String url = String.format(OPEN_ID_URL, accessToken);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = builder.build().encode().toUri();
        String resp = getRestTemplate().getForObject(uri, String.class);
        if (resp != null && resp.contains("openid")) {
            JSONObject jsonObject = ConvertToJson(resp);
            return jsonObject.getString("openid");
        }
      //log.error("QQ获得openid失败，accessToken无效，resp:{}", resp);
        return "accessToken无效";
    }

    @Override
    public String refreshToken(String code) {
        return null;
    }

    @Override
    public String getAuthorizationUrl() throws UnsupportedEncodingException {
        return String.format(AUTHORIZATION_URL, APP_ID, CALLBACK_URL, SCOPE);
    }

    @Override
    public BindUserDto getUserInfo(String accessToken, String openId) {
        String url = String.format(USER_INFO_URL, accessToken, APP_ID, openId);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = builder.build().encode().toUri();
        String resp = getRestTemplate().getForObject(uri, String.class);
        JSONObject data = JSONObject.parseObject(resp);
        BindUserDto result = new BindUserDto();
        result.setOpenId(openId);
        result.setGender(data.getString("gender"));
        result.setAvatar(data.getString("figureurl_qq_2"));
        result.setNickname(data.getString("nickname"));
        return result;
    }
}
